/*
 *  Copyright 2005 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.common.parsers.excel;

import com.blandware.atleap.common.Constants;
import com.blandware.atleap.common.parsers.SpecificPlainTextExtractor;
import com.blandware.atleap.common.parsers.exception.PlainTextExtractorException;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;

/**
 * An extractor that extracts a plain text from MS Excel workbooks.
 *
 * @see SpecificPlainTextExtractor
 * @author Roman Puchkovskiy <a href="mailto:roman.puchkovskiy@blandware.com">
 * &lt;roman.puchkovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.6 $ $Date: 2008/07/03 11:56:22 $
 */
public class ExcelPlainTextExtractor implements SpecificPlainTextExtractor {
    /**
     * Constructs new ExcelPlainTextExtractor instance
     */
    public ExcelPlainTextExtractor() {
    }

    /**
     * Extracts a plain text from an MS Excel document.
     *
     * @param input the input stream that supplies an MS Excel document for
     * extraction
     * @param output the writer that will accept the extracted text
     * @param encoding ignored
     * @throws com.blandware.atleap.common.parsers.exception.PlainTextExtractorException throwed on exception raised during
     * extracting
     */
    public void extract(InputStream input, Writer output, String encoding)
            throws PlainTextExtractorException {
        try {
            POIFSFileSystem fs = new POIFSFileSystem(input);
            HSSFWorkbook workbook = new HSSFWorkbook(fs);
            int numberOfSheets = workbook.getNumberOfSheets();

            // Cycle through sheets
            for (int i = 0; i < numberOfSheets; i++) {
                // Extract a sheet name, if exists
                String sheetName = workbook.getSheetName(i);
                if (sheetName != null) {
                    output.write(sheetName);
                    output.write(Constants.EOL);
                }
                HSSFSheet sheet = workbook.getSheetAt(i);
                if (sheet != null) {
                    int firstRowNumber = sheet.getFirstRowNum();
                    int lastRowNumber = sheet.getLastRowNum();
                    // Cycle through rows
                    for (int j = firstRowNumber; j <= lastRowNumber; j++) {
                        HSSFRow row = sheet.getRow(j);
                        if (row != null) {
                            short firstCellNumber = row.getFirstCellNum();
                            short lastCellNumber = row.getLastCellNum();
                            // This variable is needed to prevent extra spaces
                            // at beginning of lines
                            boolean cellIsPut = false;
                            // Cycle throgh cells
                            for (short k = firstCellNumber; k <= lastCellNumber; k++) {
                                HSSFCell cell = row.getCell(k);
                                if (cell != null) {
                                    int type = cell.getCellType();
                                    String value;
                                    switch (type) {
                                    case HSSFCell.CELL_TYPE_NUMERIC:
                                        value = "" + cell.getNumericCellValue();
                                        break;
                                    case HSSFCell.CELL_TYPE_STRING:
                                        value = cell.getRichStringCellValue().getString();
                                        break;
                                    case HSSFCell.CELL_TYPE_FORMULA:
                                        value = "" + cell.getNumericCellValue();
                                        break;
                                    case HSSFCell.CELL_TYPE_BLANK:
                                        value = "";
                                        break;
                                    case HSSFCell.CELL_TYPE_BOOLEAN:
                                        value = cell.getBooleanCellValue()
                                                ? "true" : "false";
                                        break;
                                    case HSSFCell.CELL_TYPE_ERROR:
                                        value = "";
                                        break;
                                    default:
                                        value = "";
                                        break;
                                    }
                                    if (cellIsPut) {
                                        output.write(' ');
                                    } else {
                                        cellIsPut = true;
                                    }
                                    output.write(value);
                                }
                            } // loop through cells
                            output.write(Constants.EOL);
                        }
                    } // loop through rows
                }
            } // loop through sheets
        } catch (IOException e) {
            throw new PlainTextExtractorException(e);
        }
    }

    /**
     * @see com.blandware.atleap.common.parsers.SpecificPlainTextExtractor#getUsedEncoding() 
     */
    public String getUsedEncoding() {
        return null;
    }
}
